﻿using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class Capsule : MonoBehaviour
{
    private AssetBundleManifest _bundleManifest; //
    private List<string> _dependencies = new List<string>(); // 记录已经加载的依赖

    private readonly string _rootDirectory = "AssetBundles/YiBaiXuNiZhuBo/";
    
    // 女性资源包信息
    private readonly string _femaleName = "inner-female";
    private readonly string[] _femalelimbs = { "femalesuti", "femaleface1", "Hai1Base", "dress1", "shoes1" };
    
    // 男性资源包信息
    private readonly string _maleName = "inner-male";
    private readonly string[] _malelimbs = { "malesuti", "maleface1", "malehair1", "maletops", "maleshoes1" };

    void Start()
    {
        GetFileName("D:\\UnityWorkspace\\unity-vtuber\\AssetBundles\\YiBaiXuNiZhuBo\\inner-female");
        
        _dependencies.Clear();
        LoadMainBundle();
        GenerateFemale();
        // GenerateMale();
        
        // LoadDependencies();
        // LoadFromFile(_rootDirectory + _femaleName);
    }

    private void LoadMainBundle()
    {
        //加载生成AB包文件时系统自动生成的一个名字跟文件目录一样的后缀为manifest包
        AssetBundle manifestAb = AssetBundle.LoadFromFile("AssetBundles/YiBaiXuNiZhuBo/YiBaiXuNiZhuBo");

        //获取到他的AssetBundleManifest文件
        AssetBundleManifest manifest = manifestAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

        _bundleManifest = manifest;
    }

    private void GenerateMale()
    {
        
        LoadBundleDepends(_maleName);
        
        AssetBundle ab = AssetBundle.LoadFromFile(_rootDirectory + _maleName);

        foreach (string limbName in _malelimbs)
        {
            //获取可使用AssetBundle这个类里面的LoadAsset<T>(string name)方法获取资源
            GameObject prefab = ab.LoadAsset<GameObject>(limbName);
            Instantiate(prefab, transform); //实例化这个游戏物体
        }
    }

    /// <summary>
    /// 加载指定资源包的依赖
    /// </summary>
    /// <param name="bundleName">资源包名字</param>
    private void LoadBundleDepends(string bundleName)
    {
        string[] strs = _bundleManifest.GetAllDependencies(bundleName); //获取到传进去的包的所有依赖的包的名字

        //遍历并加载所有依赖的包
        foreach (string name in strs)
        {
            if (_dependencies.Contains(name))
            {
                break;
            }
            //加载依赖,将文件的根目录(我们打包出来的包的保存路径)+包名(即我们自己定义的AssetBundle打包的名字和后缀)传进去
            AssetBundle.LoadFromFile(_rootDirectory + name);
            _dependencies.Add(name);
        }
    }

    private void GenerateFemale()
    {
        LoadBundleDepends(_femaleName);
        
        AssetBundle ab = AssetBundle.LoadFromFile(_rootDirectory + _femaleName);

        foreach (string limbName in _femalelimbs)
        {
            //获取可使用AssetBundle这个类里面的LoadAsset<T>(string name)方法获取资源
            GameObject prefab = ab.LoadAsset<GameObject>(limbName);
            Instantiate(prefab, transform); //实例化这个游戏物体
            // todo: 绑定共享骨骼
        }
    }

    private void GetFileName(string filepath)
    {
        string directoryname = Path.GetDirectoryName(filepath);
        string filename = Path.GetFileNameWithoutExtension(filepath);
        print($"[ info: ] 获取到的目录名字为： {directoryname}");
        print($"[ info: ] 获取到的文件名字为： {filename}");
        print($"[ info: ] 获取到的文件名字为： {Path.GetFileName(filepath)}");
    }

    /// <summary>
    /// 本地加载AssetBundle
    /// </summary>
    /// <param name="path">AB包存在本地的路径</param>
    private void LoadFromFile(string path)
    {
        AssetBundle ab = AssetBundle.LoadFromFile(path);

        //获取可使用AssetBundle这个类里面的LoadAsset<T>(string name)方法获取资源
        GameObject wallPrefab = ab.LoadAsset<GameObject>("femalesuti");

        Instantiate(wallPrefab, transform); //实例化这个游戏物体
    }

    //加载这个物体的依赖
    private void LoadDependencies(string bundleName)
    {
        //加载生成AB包文件时系统自动生成的一个名字跟文件目录一样的后缀为manifest包
        AssetBundle manifestAb = AssetBundle.LoadFromFile("AssetBundles/YiBaiXuNiZhuBo/YiBaiXuNiZhuBo");

        //获取到他的AssetBundleManifest文件
        AssetBundleManifest manifest = manifestAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

        string[] strs = manifest.GetAllDependencies(bundleName); //获取到传进去的包的所有依赖的包的名字

        //遍历并加载所有依赖的包
        foreach (string name in strs)
        {
            if (_dependencies.Contains(name))
            {
                break;
            }
            //加载依赖,将文件的根目录(我们打包出来的包的保存路径)+包名(即我们自己定义的AssetBundle打包的名字和后缀)传进去
            AssetBundle.LoadFromFile(_rootDirectory + name);
            _dependencies.Add(name);
        }
    }
}